// enum Sortable {
//     normal,
//     desc,
//     asc,
// }

// type Sortable = "normal" | "desc" | "asc";
// type func = (a?, b?, c?) => any

// interface Store {
//     readonly name: string;
//     readonly ajaxRequest: func,
//     readonly interceptResponse?: func,
//     readonly storage?: string,
//     readonly sortable?: [Sortable, string],
//     // default?: any,
//     formData?: object,
// }


// const list: Store[] = [{
//     name: "name",
//     ajaxRequest: function () { },
//     target: "data",
//     default: [],
// }]

// 按需加载模板
function getResponse(data, obj) {
    const { interceptResponse, sortable = [] } = obj,
        [sort, key] = sortable;
    if (typeof interceptResponse === 'function') {
        data = interceptResponse(data);
    }
    if (!(data instanceof Array)) return data;
    if (sort === 'desc') return data.sort(function (pre, cur) {
        return key ? (pre[key] > cur[key] ? -1 : 1) : (pre > cur ? -1 : 1)
    })
    if (sort === 'asc') return data.sort(function (pre, cur) {
        return key ? (pre[key] > cur[key] ? 1 : -1) : (pre > cur ? 1 : -1)
    })
    return data;
}

function getStorage(type) {
    if (type === "localStorage") return localStorage;
    return sessionStorage;
}
function nameSpaced(prefix = '', name = '') {
    return prefix + name.toUpperCase();
}
const statusObj = {};
let NAMESPACE = 0;
export function template(list = [], namespace = '') {
    
    const Namespace = `${namespace || ("NAMESPACE" + NAMESPACE++)}`.toUpperCase() + '_';
    const state = {
        __list__: [],
    },
        getters = {},
        mutations = {
            clearStore(state, payload) {
                const isClearStore = payload === true;
                state.__list__.forEach(function (item) {
                    const { name, storage, upperName } = item;
                    if (name && (isClearStore || payload === name)) {
                        getStorage(storage).removeItem(upperName);
                        // console.log(upperName, 'upperName');
                        state[name] = [];
                        if (isClearStore) {//防止更新循环
                            statusObj[upperName] = false;
                        } else {
                            setTimeout(() => {//防止更新循环
                                statusObj[upperName] = false;
                            }, 700);
                        }
                    }
                })
            },
        },
        actions = {
            actionInit({ commit, dispatch, state }, updateInit) {
                state.__Dispatch__ = dispatch;
                if (updateInit) commit('clearStore', true);
            },
            clearStore({ commit }) {
                commit('clearStore', true);
            }
        };
    list.forEach(function (item) {
        const { name, ajaxRequest, formData } = item,
            humpName = name[0].toUpperCase() + name.substring(1),
            upperName = nameSpaced(Namespace, name),
            storage = getStorage(item.storage);
        state.__list__.push({
            storage: item.storage,
            name,
            upperName
        });
        try {
            state[name] = JSON.parse(JSON.parse(storage.getItem(upperName)).data) || [];
        } catch (error) {
            state[name] = [];
        }
        getters['get' + humpName] = function (state) {
            if (!statusObj[upperName] && state.__Dispatch__) {
                statusObj[upperName] = true;
                state.__Dispatch__('action' + humpName);
            }
            return state[name]
        }
        mutations[name] = function (state, payload) {
            storage.setItem(upperName,JSON.stringify(payload))
            state[name] = payload;
        }
        actions['action' + humpName] = async function ({ commit }, payload = false) {
            if (!payload && storage.getItem(upperName)) {
                // commit(name, JSON.parse(data));
                return;
            }
            return ajaxRequest(formData).then(function (res) {
                const data = getResponse(res.data, item);
                if (data) return commit(name, data);
                commit('clearStore', name);
            }).catch(function () {
                commit('clearStore', name);
            });
        }
    })
    return {
        namespaced: true,
        state,
        getters,
        mutations,
        actions
    }
}

export default function mixins(list, target, namespace) {
    
    const store = template(list, namespace);
    if (!target) return store;
    for (let key in store) {
        if (key !== 'namespaced') {
            store[key] = Object.assign(store[key], target[key]);
        }
    }
    return store;
}
